declare const module: any;
import { NestFactory } from '@nestjs/core';
import { AppModule } from './app.module';
import {
  VersioningType,
  ValidationPipe,
  HttpStatus,
  BadRequestException,
} from '@nestjs/common';
import { Request, Response, NextFunction } from 'express';
import * as cors from 'cors';
import { NestExpressApplication } from '@nestjs/platform-express';
import { join } from 'path';
import { InterceptorResponse } from './common/response';
import { HttpFilter } from './common/exceptionFilter';
import { SwaggerModule, DocumentBuilder } from '@nestjs/swagger';
import { getConfig } from 'utils';

// 全局中间件，局部接口中间件可查去user.module.ts中查看
function GlobalMiddleware(req: Request, res: Response, next: NextFunction) {
  next();
}

async function bootstrap() {
  const app = await NestFactory.create<NestExpressApplication>(AppModule, {
    logger: ['error', 'warn']
  });
  app.setGlobalPrefix('api'); // 添加统一前缀
  app.use(cors()); // 开启跨域处理
  // 开启版本控制
  app.enableVersioning({
    type: VersioningType.URI,
  });
  const config = new DocumentBuilder()
    .setTitle('Cats example')
    .setDescription('The cats API description')
    .setVersion('1.0')
    .addTag('cats')
    .build();

  // 是否忽略全局统一前缀
  const document = SwaggerModule.createDocument(app, config, {
    ignoreGlobalPrefix: false,
  });
  SwaggerModule.setup('api-docs', app, document);
  // 全局中间件
  app.use(GlobalMiddleware);
  // 全局响应拦截，统一返回格式
  app.useGlobalInterceptors(new InterceptorResponse());
  // 全局异常拦截
  app.useGlobalFilters(new HttpFilter());
  // 全局接口数据校验
  app.useGlobalPipes(
    new ValidationPipe({
      transform: true,
      whitelist: true,
      // 禁止非白名单参数，存在非白名单属性报错。此项可根据需求而定，如果设置false，将剥离非白名单属性
      forbidNonWhitelisted: true,
      // 设置校验失败后返回的http状态码
      errorHttpStatusCode: HttpStatus.BAD_REQUEST,
      exceptionFactory: (errors) => {
        const msg = Object.values(errors[0].constraints)[0];
        return new BadRequestException({
          message: msg,
          status: HttpStatus.BAD_REQUEST,
        });
      },
    }),
  );
  // 热重载
  if (module.hot) {
    module.hot.accept();
    module.hot.dispose(() => app.close());
  }
  // 托管静态资源第二个参数是前置路径，可不配置
  app.useStaticAssets(join(__dirname, '..', 'statics'), { prefix: '/public/' });
  const port = getConfig().HOST_PORT
  await app.listen(port, '0.0.0.0');
  console.log(`server is runing at port:${port}`);
  console.log(`swagger is runing at HOSTNAME:${getConfig().SWAGGER_HOST}/api-docs`)
}
bootstrap();
